/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.luedinski.objects;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Iterator;
import org.jgrapht.EdgeFactory;
import org.jgrapht.GraphPath;
import org.jgrapht.alg.KShortestPaths;
import org.jgrapht.graph.DefaultWeightedEdge;
import org.jgrapht.graph.DefaultDirectedWeightedGraph;

import com.luedinski.utilities.ConnectionPooling;

/**
 * Die Klasse Net stellt das Streckennetz dar.
 * Statische klasse bei server start
 * @author lueder
 */
@SuppressWarnings(value={"rawtypes", "unchecked"})
public class Net {
   
	private DefaultDirectedWeightedGraph net;
    
    /**
     * Default-Kontruktor
     */
   
	public Net(){
         net = new DefaultDirectedWeightedGraph(DefaultWeightedEdge.class);
         refreshFromSql();
    }
    
    public Net(EdgeFactory ef){
        net = new DefaultDirectedWeightedGraph(ef);
    }
            
    
    /**
     * Fügt ein Bahnhof dem Streckennetz hinzu.
     * @param s Bahnhof
     */
    public void addStation(Station s){
        net.addVertex(s);
    }
    
    /**
     * Fügt eine Verbindung zwischen zwei Bahnhöfen hinzu und berechnet
     * automatisch die Streckenlänge. Ist der Bahnhof noch nicht vorhanden,
     * wird er ins Netz eingefügt.
     * @param s1
     * @param s2 
     */
    public void addConnection(Station s1, Station s2){
        if(!net.containsVertex(s1))
            net.addVertex(s1);
        if(!net.containsVertex(s2))
            net.addVertex(s2);
        net.setEdgeWeight(net.addEdge(s1, s2), Station.computeGeoDistance(s1, s2));
    }
    
    /**
     * Gibt das gesamte Streckennetz zurück, um Stationen den BaseGraph zur
     * Verfügung zu stellen.
     * @return SimpleWeightedGraph
     */
    public DefaultDirectedWeightedGraph getNet(){
        return net;
    }
    
    public Iterator<GraphPath<Station, Station>> getRoutes(Station origin, Station destination, int maxRoutes){
        KShortestPaths ksp = new KShortestPaths(net, origin, maxRoutes);
        return ksp.getPaths(destination).iterator();
    }
    
    public double getDistance(Station s1, Station s2){
        return net.getEdgeWeight(net.getEdge(s1, s2));
    }
    
    public DefaultWeightedEdge getEdge(Station start, Station end){
        return (DefaultWeightedEdge)net.getEdge(start, end);
    }
    
    @Override
    public String toString(){
        return net.toString();
    }
    
    public void refreshFromSql(){
    	Connection conn = null;
		Statement stmt = null;
		ResultSet rs = null;
		String sql = "SELECT source_id, target_id FROM edge";

		try {
			conn = ConnectionPooling.getConnection();
			stmt = conn.createStatement();
			rs = stmt.executeQuery(sql);
			while(rs.next()){
				addConnection(Station.fromSql(rs.getInt(1)), Station.fromSql(rs.getInt(2)));
			}
			

		} catch (Exception e) {
		} finally {
			if (rs != null)
				try {
					rs.close();
				} catch (Exception e) {
				}
			if (stmt != null)
				try {
					stmt.close();
				} catch (Exception e) {
				}
			if (conn != null)
				try {
					conn.close();
				} catch (Exception e) {
				}
		}
    }
    
    
            
}
